package com.api.devices.service.impl;

import com.api.common.utils.DateUtils;
import com.api.devices.domain.query.SourceQuery;
import com.api.devices.domain.vo.SourceVo;
import com.api.devices.service.ISourceService;
import com.hierynomus.msdtyp.AccessMask;
import com.hierynomus.mssmb2.SMB2CreateDisposition;
import com.hierynomus.mssmb2.SMB2ShareAccess;
import com.hierynomus.smbj.SMBClient;
import com.hierynomus.smbj.auth.AuthenticationContext;
import com.hierynomus.smbj.connection.Connection;
import com.hierynomus.smbj.session.Session;
import com.hierynomus.smbj.share.DiskShare;
import com.hierynomus.smbj.share.File;
import org.springframework.stereotype.Service;

//import java.io.FileInputStream;
//import java.io.IOException;
//import java.nio.file.Files;
//import java.nio.file.Path;
//import java.nio.file.Paths;
//import java.nio.file.attribute.BasicFileAttributes;
import java.io.InputStream;
import java.util.*;

@Service
public class SourceServiceImpl implements ISourceService {
    private static long oneDayTime = 24 * 60 * 60 * 1000;
    private static String shareName = "dat";

    @Override
    public List fileData(SourceVo vo) throws Exception{
        List dataList = new ArrayList<>();
        Long st = vo.getStartTime().getTime();
        Long et = vo.getEndTime().getTime();
        int d = (int) ((et - st) / (oneDayTime));
        SMBClient client = new SMBClient();
        Connection connection = client.connect(vo.getIp());
        AuthenticationContext authContext = new AuthenticationContext(vo.getUser(), vo.getPassword().toCharArray(), "");
        Session session = connection.authenticate(authContext);
        DiskShare share = (DiskShare) session.connectShare(shareName);


        List<String> fileNames = fileNameList(vo);
        int bytesPerLine = 16; // 每行显示的16进制字节数
        for(String filePath: fileNames){
            try (File file = share.openFile(filePath,
                    EnumSet.of(AccessMask.GENERIC_READ),
                    null,
                    SMB2ShareAccess.ALL,
                    SMB2CreateDisposition.FILE_OPEN,
                    null)) {
                InputStream is = file.getInputStream();
                byte[] buffer = new byte[bytesPerLine];
                int bytesRead;
                long offset = 0;
                int init = 0;
                long v = 0;
                Long time = 0L;
                while ((bytesRead = is.read(buffer)) != -1) {
                    if (init == 0) {
                        String strTime = String.format("%02x", buffer[3])
                                + String.format("%02x", buffer[2])
                                + String.format("%02x", buffer[1])
                                + String.format("%02x", buffer[0]);
                        String param = String.format("%02x", buffer[11])
                                + String.format("%02x", buffer[10]);
                        v = Long.parseLong(param, 16);
                        time = Long.parseLong(strTime, 16) * 1000;

                    } else {
//                        int index = (Integer.parseInt(vo.getDatCol()) - 1) * 2;
                        int index = (vo.getAccess() - 1) * 2;
                        String strParam = String.format("%02x", buffer[index + 1]) + String.format("%02x", buffer[index]);
                        Integer param = Integer.parseInt(strParam, 16);
                        Long t = time + init;
//                    Long val = ((param/65535)*240-120);
                        double val = (((double) param / 65535) * 240 - 120);
                        List l = new ArrayList();
                        l.add(time);
                        l.add(val);
                        dataList.add(l);
                    }
                    init++;
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        client.close();
        return dataList;
    }

    @Override
    public List<SourceQuery> realTime(SourceVo vo) throws Exception {
//        String filePath = getFilePath(vo);
//        return getData(vo, filePath);
        return getData(vo);
    }


    private List<SourceQuery> getData(SourceVo vo) throws Exception{
//        String date = DateUtils.parseDateToStr(DateUtils.YYYYMMDD, new Date());
        List<SourceQuery> dataList = new ArrayList<>();
        Long st = vo.getStartTime().getTime();
        Long et = vo.getEndTime().getTime();
        int d = (int) ((et - st) / (oneDayTime));
        SMBClient client = new SMBClient();
        Connection connection = client.connect(vo.getIp());
        AuthenticationContext authContext = new AuthenticationContext(vo.getUser(), vo.getPassword().toCharArray(), "");
        Session session = connection.authenticate(authContext);
        DiskShare share = (DiskShare) session.connectShare(shareName);


        List<String> fileNames = fileNameList(vo);
        int bytesPerLine = 16; // 每行显示的16进制字节数
        for(String filePath: fileNames){
            try (File file = share.openFile(filePath,
                    EnumSet.of(AccessMask.GENERIC_READ),
                    null,
                    SMB2ShareAccess.ALL,
                    SMB2CreateDisposition.FILE_OPEN,
                    null)) {
                InputStream is = file.getInputStream();
                byte[] buffer = new byte[bytesPerLine];
                int bytesRead;
                long offset = 0;
                int init = 0;
                long v = 0;
                Long time = 0L;
                while ((bytesRead = is.read(buffer)) != -1) {
                    if (init == 0) {
                        String strTime = String.format("%02x", buffer[3])
                                + String.format("%02x", buffer[2])
                                + String.format("%02x", buffer[1])
                                + String.format("%02x", buffer[0]);
                        String param = String.format("%02x", buffer[11])
                                + String.format("%02x", buffer[10]);
                        v = Long.parseLong(param, 16);
                        time = Long.parseLong(strTime, 16) * 1000;

                    } else {
//                        int index = (vo.getDatCol() - 1) * 2;
                        int index = (vo.getAccess() - 1) * 2;
                        String strParam = String.format("%02x", buffer[index + 1]) + String.format("%02x", buffer[index]);
                        Integer param = Integer.parseInt(strParam, 16);
                        Long t = time + init;
//                    Long val = ((param/65535)*240-120);
                        double val = (((double) param / 65535) * 240 - 120);
//                        System.out.println(t + ";[strParam]:" + strParam
//                                + ";[v]:" + v
//                                + ";[param]:" + param
//                                + ";[val]:" + val
//                                + ";[init]:" + init
//                                + ";[time]:" + time);
//                        JSONObject jo = new JSONObject();
//                        jo.put("time", time);
//                        jo.put("val", val);
//                        dataList.add(jo);
                        dataList.add(new SourceQuery(time,val));
                    }
                    init++;
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        client.close();
        return dataList;
    }
    private List<String> fileNameList(SourceVo sourceVo){
        List<String> fileNames = new ArrayList<>();
        Long st = sourceVo.getStartTime().getTime();
        Long et = sourceVo.getEndTime().getTime();
//        int d = (int) ((et - st) / (oneDayTime));
        int times = Math.toIntExact(et - st);
        String initFilePath = sourceVo.getFileCode()+"/dat/";
        for(int i=0;i<times;i=i+(60*1000)){
            Long datetime = st + i;
            String YYYYMMDD = DateUtils.parseDateToStr(DateUtils.YYYYMMDD, new Date(datetime));
            String datFile = DateUtils.parseDateToStr(DateUtils.YYYYMMDDHHMMSS, new Date(datetime)) + ".dat";
            fileNames.add(initFilePath+YYYYMMDD+"/"+datFile);
        }
        return fileNames;
    }
}
